package com.simons.module.importFile.service;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import com.simons.common.exception.CommonErrorType;
import com.simons.common.exception.CommonException;
import com.simons.common.utils.date.DateUtils;
import com.simons.common.utils.file.office.ExcelFactory;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public abstract class AbstractImportService {
	// 导入的sheet名
	protected String sheetName;

	// 导入文件的存放地方
	protected String exportPlace;

	// 导入的数据对应表头的字段
	protected String[] fieldNames;

	/**
	 * 通过MultipartFile导入文件信息
	 * 
	 * @param file
	 * @param beanInfo
	 * @return
	 * @throws Exception 
	 */
	public <T> List<T> getList(MultipartFile file, Class<T> clazz)
			throws Exception {
		String dateStr = DateUtils.format(new Date());

		String fileName = dateStr + file.getOriginalFilename();
		String desPath = exportPlace;

		File folder = new File(desPath);
		if (!folder.exists()) {
			folder.mkdirs();
		}
		File destFile = new File(desPath + fileName);
		OutputStream stream = null;
		try {
			// 输出文件
			byte[] bytes = file.getBytes();
			stream = new BufferedOutputStream(new FileOutputStream(destFile));
			stream.write(bytes);
			return this.readFile(destFile, clazz);
		} catch (IOException e) {
			log.error("", e);
			throw new CommonException(CommonErrorType.COMMON_ERROR, "读取excel文件失败");
		} finally {
			IOUtils.closeQuietly(stream);
			FileUtils.deleteQuietly(destFile);
		}
	}

	/**
	 * 通过MultipartFile导入文件信息
	 * 
	 * @param input
	 * @param beanInfo
	 * @return
	 * @throws Exception 
	 */
	public <T> List<T> getList(InputStream input, String fileName, Class<T> clazz)
			throws Exception {
		try {
			// 输出文件
			return this.readFile(input, fileName, clazz);
		} catch (IOException e) {
			log.error("", e);
			throw new CommonException(CommonErrorType.COMMON_ERROR, "读取excel失败");
		} finally {
			IOUtils.closeQuietly(input);
		}
	}

	/**
	 * 通过已存在的file导入文件
	 * 
	 * @param file
	 * @param clazz
	 * @return
	 * @throws Exception 
	 */
	public <T> List<T> getList(File file, Class<T> clazz) throws Exception {
		return this.readFile(file, clazz);
	}

	/**
	 * 导入文件的具体操作
	 * 
	 * @param destFile
	 * @param clazz
	 * @return
	 * @throws Exception 
	 */
	private <T> List<T> readFile(File destFile, Class<T> clazz) throws Exception {
		// 获取sheet
		if (sheetName == null) {
			throw new CommonException(CommonErrorType.COMMON_ERROR, "系统尚未定义sheet名");
		}
		int sheet = ExcelFactory.getSheetBySheetName(destFile, sheetName);
		if (sheet == -1) {
			throw new CommonException(CommonErrorType.COMMON_ERROR, "文件中不存在对应的sheet");
		}
		// 解析excel
		return ExcelFactory.read(destFile, sheet, fieldNames, clazz);
	}

	/**
	 * 导入文件的具体操作
	 * 
	 * @param input
	 * @param clazz
	 * @return
	 * @throws Exception 
	 */
	private <T> List<T> readFile(InputStream input, String fileName, Class<T> clazz) throws Exception {
		// 获取sheet
		if (sheetName == null) {
			throw new CommonException(CommonErrorType.COMMON_ERROR, "系统尚未定义sheet名");
		}
		// 解析excel
		return ExcelFactory.read(input, fileName, 0, fieldNames, clazz);
	}
}
